@tool
class_name PropertyBox
extends PanelContainer

#region 属性
@export var property_name_lab:Label
@export var property_value_string:LineEdit
@export var property_value_int:SpinBox
@export var property_value_float:SpinBox
@export var property_value_bool:CheckBox
@export var property_value_enum:OptionButton
@export var property_by_data_cb:CheckBox
@export var property_value_data:OptionButton
var visual_view:VisualView
var property_name:String
var property_value
var property_value_type
var target
var connect_obj_dict:Dictionary[Signal,ConnectObj] = {}
#endregion
#region 字段
#endregion
#region 信号
#endregion

#region 基类方法
#endregion
#region 公共方法
func init(visual_view:VisualView,target,property_name:String,can_edit:bool = true) -> void:
	self.visual_view = visual_view
	self.target = target
	self.property_name = property_name
	property_name_lab.text = property_name
	property_value = target.get(self.property_name)
	property_value_type = typeof(property_value)
	update_property_data_list()
	update_property_value()
	
	connect_obj_dict[property_value_string.text_changed] = ConnectObj.new(property_value_string.text_changed,[_on_property_value_string_changed])
	connect_obj_dict[property_value_int.value_changed] = ConnectObj.new(property_value_int.value_changed,[_on_property_value_int_changed])
	connect_obj_dict[property_value_float.value_changed] = ConnectObj.new(property_value_float.value_changed,[_on_property_value_float_changed])
	connect_obj_dict[property_value_bool.toggled] = ConnectObj.new(property_value_bool.toggled,[_on_property_value_bool_changed])
	connect_obj_dict[property_value_enum.item_selected] = ConnectObj.new(property_value_enum.item_selected,[_on_property_value_enum_changed])
	connect_obj_dict[property_by_data_cb.toggled] = ConnectObj.new(property_by_data_cb.toggled,[_on_property_by_data_changed])
	connect_obj_dict[property_value_data.item_selected] = ConnectObj.new(property_value_data.item_selected,[_on_property_value_data_changed])
	
	connect_obj_dict[visual_view.property_added] = ConnectObj.new(visual_view.property_added,[_on_property_added])
	connect_obj_dict[visual_view.property_removed] = ConnectObj.new(visual_view.property_removed,[_on_property_removed])
	connect_obj_dict[visual_view.property_name_changed] = ConnectObj.new(visual_view.property_name_changed,[_on_property_name_changed])
	connect_obj_dict[visual_view.property_type_changed] = ConnectObj.new(visual_view.property_type_changed,[_on_property_type_changed])
	connect_obj_dict[visual_view.property_value_changed] = ConnectObj.new(visual_view.property_value_changed,[_on_property_value_changed])
func get_value():
	return property_value
func set_value(value):
	property_value = value
	save()
## 更新PropertyValue的种类显示
func update_property_value():
	property_value_string.visible = false
	property_value_int.visible = false
	property_value_float.visible = false
	property_value_bool.visible = false
	property_value_enum.visible = false
	var info = Utils.get_property_info(target,property_name)
	if info and info.hint in [PROPERTY_HINT_ENUM,PROPERTY_HINT_ENUM_SUGGESTION] and info.hint_string:
		property_value_enum.clear()
		var idx = 0
		var select_idx
		var real_idx = -1
		for item in info.hint_string.split(","):
			real_idx += 1
			item = item.split(":")
			var n = item[0]
			var i = idx
			if item.size() > 1:
				i = int(item[1])
			else:
				idx += 1
			property_value_enum.add_item(n)
			if i == property_value:
				select_idx = real_idx
		if select_idx:
			property_value_enum.select(select_idx)
		property_value_enum.visible = true
		return
	match typeof(property_value):
		TYPE_STRING:
			property_value_string.text = property_value
			property_value_string.visible = true
			return
		TYPE_INT:
			property_value_int.value = property_value
			property_value_int.visible = true
			return
		TYPE_FLOAT:
			property_value_float.value = property_value
			property_value_float.visible = true
			return
		TYPE_BOOL:
			property_value_bool.button_pressed = property_value
			property_value_bool.visible = true
			return
func save():
	target.set(property_name,property_value)
func update_property_data_list():
	property_value_data.clear()
	var skill:Skill = visual_view.get_cur_skill()
	if not skill:
		return
	for key in skill.init_data.keys():
		property_value_data.add_item(key)
func set_property_read_only(read_only:bool):
	property_value_string.editable = not read_only
	property_value_int.editable = not read_only
	property_value_float.editable = not read_only
	property_value_bool.disabled = not read_only
	property_value_enum.disabled = not read_only
#region 信号回调
func _on_property_value_string_changed(new_text: String):
	set_value(new_text)
func _on_property_value_int_changed(value):
	set_value(value)
func _on_property_value_float_changed(value):
	set_value(value)
func _on_property_value_bool_changed(toggled_on: bool):
	set_value(toggled_on)
func _on_property_value_enum_changed(index: int):
	set_value(index)
func _on_property_by_data_changed(toggled_on: bool):
	set_property_read_only(toggled_on)
	var skill:Skill = visual_view.get_cur_skill()
	if not skill:
		return
	var text = property_value_data.get_item_text(property_value_data.selected)
	if not text:
		return
	var value = skill.init_data.get(text)
	if not value:
		return
	if typeof(value) != property_value_type:
		return
	set_value(value)
	_on_property_value_data_changed(property_value_data.selected)
func _on_property_value_data_changed(index: int):
	if not property_by_data_cb.button_pressed:
		return
	var skill:Skill = visual_view.get_cur_skill()
	if not skill:
		return
	update_property_value()
func _on_property_added():
	update_property_data_list()
func _on_property_removed(property_name:String):
	if property_by_data_cb.button_pressed and property_value_data.get_item_text(property_value_data.get_selected_id()) == property_name:
		property_by_data_cb.button_pressed = false
	update_property_data_list()
func _on_property_name_changed():
	update_property_data_list()
func _on_property_type_changed():
	_on_property_value_data_changed(property_value_data.selected)
func _on_property_value_changed(value):
	set_value(value)
	_on_property_value_data_changed(property_value_data.selected)
#endregion
#endregion
#region 私有方法
#endregion
#region 生命周期函数
func _notification(what: int) -> void:
	if what == NOTIFICATION_PREDELETE:
		for connect_obj in connect_obj_dict.values():
			if connect_obj:
				connect_obj.disconnect_all()
#endregion
